package top.xiaoshuaila.mail;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import top.xiaoshuaila.pojo.Employee;
import top.xiaoshuaila.pojo.MailConstants;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.Date;

@Component
public class Mailreciver {

    private static final Logger LOGGER=
            LoggerFactory.getLogger(Mailreciver.class);

    //Mail发送
    @Autowired
    private JavaMailSender javaMailSender;
    //配置文件的mail参数
    @Autowired
    private MailProperties mailProperties;
    //theymeledf引擎
    @Autowired
    private TemplateEngine templateEngine;
    @Autowired
    private RedisTemplate redisTemplate;

    //接收来自mail.welcome管道的信息,每收到一个employee对象处理一次
    @RabbitListener(queues = MailConstants.QUEUE_NAME)
    //接收spring的消息和rabbitmq的渠道
    /*
    * 在Message中的headers
    * headers={amqp_receivedDeliveryMode=PERSISTENT,
    * amqp_receivedRoutingKey=javaboy.mail.routing.key,
    * amqp_receivedExchange=javaboy.mail.exchange,
    * spring_returned_message_correlation=8170350b-3b4d-4f20-89fc-f9e72bf754cb
*/
    public void handler(Message message,Channel channel){
        //从message的paylod获得employ对象
        Employee employee=(Employee)message.getPayload();
        MessageHeaders headers=message.getHeaders();
        //从message的header获得手动确认的deliveryTag
        long tag = (long) headers.get(AmqpHeaders.DELIVERY_TAG);
        //从message获得作为判断的msgid
        String msgId=(String)headers.get(
                "spring_returned_message_correlation");
        //使用HashOperations来操作redis
        HashOperations hashOperations=redisTemplate.opsForHash();
        MimeMessage msg=javaMailSender.createMimeMessage();
        MimeMessageHelper helper=new MimeMessageHelper(msg);
        try {
            //判断有没有msgid,如果有,证明已经处理过,直接返回确认ack
            if(hashOperations.entries("mail_log").containsKey(msgId))
            {
                System.out.println("已经处理过!!");
                channel.basicAck(tag,false);
                return;
            }
            //设置发送人姓名
            helper.setFrom(mailProperties.getUsername());
            //设置接收方email
            helper.setTo(employee.getEmail());
            //设置邮件名
            helper.setSubject("入职欢迎邮件");
            //设置发送的时间,但不是定时发送
            helper.setSentDate(new Date());
            //设置theymeleaf内容
            Context context=new Context();
            context.setVariable("name",employee.getName());
            context.setVariable("posName",employee.getPosition().getName());
            context.setVariable("joblevelName",
                    employee.getJoblevel().getName());
            context.setVariable("departmentName",
                    employee.getDepartment().getName());
            //将参数填充到mail.html中并转换为字符串
            String mail=templateEngine.process("mail",context);
            //设置邮件内容,并且设置为html格式
            helper.setText(mail,true);
            //发送邮件
            javaMailSender.send(msg);
            System.out.println("发送邮件成功");
            //到这里证明第一次处理该消息,加入redis,返回确认ack
            hashOperations.put("mail_log",msgId,"OK");
            channel.basicAck(tag,false);
        } catch (Exception e) {
            try {
                //出现异常,捕获后返回nack
                channel.basicNack(tag,false,true);
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            LOGGER.error("邮件发送失败..................",e.getMessage());
        }

    }

}
